﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

namespace Infrastructure.Common.JWT
{
    public class JwtHelper
    {
        private readonly JwtTokenOption _options;

        public JwtHelper(JwtTokenOption options)
        {
            _options = options;
        }
        /// <summary>
        /// 根据一个对象通过反射提供负载，生成token
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="user"></param>
        /// <returns></returns>
        public TnToken CreateToken<T>(T entity) where T : class
        {
            //定义声明的集合
            List<Claim> claims = new List<Claim>();
            //用反射把数据提供给它
            foreach (var item in entity.GetType().GetProperties())
            {
                object obj = item.GetValue(entity);
                string value = "";
                if (obj != null)
                {
                    value = obj.ToString();
                }
                claims.Add(new Claim(item.Name, value));
            }
            //根据声明 生成token字符串
            return CreateTokenString(claims);

        }
        /// <summary>
        /// 私有方法，用于生成Token字符串
        /// </summary>
        /// <param name="claims"></param>
        /// <returns></returns>
        public TnToken CreateTokenString(List<Claim> claims)
        {
            //预置荷载
            //过期时间
            DateTime expires =
            DateTime.Now.AddMinutes(_options.AccessTokenExpiresMinutes);
            var token = new JwtSecurityToken(
            issuer: _options.Issuer,//发行人
            audience: _options.Audience,//受众
            claims: claims, //携带的荷载
            notBefore: DateTime.Now, //token生成时间
            expires: expires, //token过期时间
            signingCredentials: new SigningCredentials(
            new
            SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.IssuerSigningKey)),
            SecurityAlgorithms.HmacSha256
            )
            );
            return new TnToken
            {
                Expires = expires,
                TokenStr = new JwtSecurityTokenHandler().WriteToken(token)
            };
        }
    }
}

